/* Universidad del Valle de Guatemala
 * Hoja2.java
 * Pablo Rodriguez, 12374
 * Julio Maldonado, 12377
 * Seccion 30, Algoritmos y Estructura de Datos
 * Fecha: 22/07/13
 * Driver que lee un archivo txt y calcula el resultado de la operacion utilizando notacion postfix
 */

package hoja2;
import java.io.*; // se importan algunas librerias de java para poder abrir los archivos
public class Hoja2 {

    public static void main(String[] args) {
          Calculadora<Double> c = new Calculadora<Double>(); // Se intancia la clase calculadore y se determina el tipo de dato que recibira.
          int validar = 0; //Esta variable controla si el archivo tiene un sucecion correcta o hay algo malo en el.
          File archivo = null; // variable archivo contendra la el archivo a analizar
          FileReader fr = null; // variable fr sirve para leer el arhivo mas adelante
          BufferedReader br = null; // br es una variable que servira para complementar la lectura del archivo
          
          try{  // se realiza un try catch para asegurarse que el archivo este correcto
              
              archivo= new File("C:\\Java\\datos.txt"); // se localiza el archivo a analizar
              fr = new FileReader(archivo); // se lee el archivo 
              br = new BufferedReader(fr); // el archivo se coloca en el buffer
              
              String linea; // variable linea contendra toda la cadena de caracteres que contenga el archivo
              System.out.println("Calculo");
              while((linea=br.readLine())!=null){ // mientras haya caracteres seguira ejecutandose el programa
                 
                  for(int i=0;i<linea.length(); i++){ // este for sirve paraa recorrer todos los caracteres que se encuentren en el archivo
                    
                      System.out.print(linea.charAt(i));// Se imprime el string de archivo datos.txt
                      int comparar = (int)linea.charAt(i); // comparar en una variable que contendra los codigos char de todo lo que se encuentre en el archivo.
                      
                      if (comparar>=48 &&  comparar<=57 ) { // si la comparaacion que hace con los codigos char estan entre 49 y 57 significa que se ha encontrado un numero.
                          if(c.size()!=2){ // esta condicion revisa si en el stack hay mas de dos elementos, si no hay entonces guarda el numero siguiente y si hay mas de dos significa que el archivo tiene una sucesion incorrecta
                              double numero = Double.parseDouble(linea.substring(i,i+1)); // la variable numero connvierte el carcter string en un double.
                              c.push(numero); // esto almacena el numero en la pila.
                              
                        }else{
                          
                          System.out.println("El Archivo tiene una secuencia mala"); // si hay mas de dos numeros queriendo entrar a la pila, este es el mensaje que saldra por progrmacion defensiva
                          validar = validar+1; // la variable validar se activa porque hay algo malo en el archivo
                          
                          
                          }
             
                      
                        }else{ // si no se dectan numeros entonces eso quiere decir que son espacion o operaciones y en esta parte solo se toman encuenta las operaciones por lo que los espacios desaparecen automaticamente
                          
                          if ((int)linea.charAt(i)==42){ // aqui se compara si el operando es una mulplicacion y se quitan los dos numeros que esxisten en la pila, hace la operacion y el resultado se introduce otra vez en la pila.
                          
                          double num1=c.pop();
                          double num2=c.pop();
                          
                          double multiplicacion = num1*num2;
                          
                          c.push(multiplicacion);

                          
                          
                          }
                          
                           if ((int)linea.charAt(i)==43){  // aqui se compara si el operando es una suma y se quitan los dos numeros que esxisten en la pila, hace la operacion y el resultado se introduce otra vez en la pila.
                          
                          double num3=c.pop();
                          double num4=c.pop();
                          
                          double suma = num3+num4;
                          
                          c.push(suma);
                          }
                           
                           if ((int)linea.charAt(i)==45){  // aqui se compara si el operando es una resta y se quitan los dos numeros que esxisten en la pila, hace la operacion y el resultado se introduce otra vez en la pila.
                          
                          double num5=c.pop();
                          double num6=c.pop();
                          
                          double resta = num6-num5;
                          
                          c.push(resta);
            
                          }
                           
                           
                           if ((int)linea.charAt(i)==47){  // aqui se compara si el operando es una division y se quitan los dos numeros que esxisten en la pila, hace la operacion y el resultado se introduce otra vez en la pila.
                               
                              
                               
                               double num7=c.pop();
                               double num8=c.pop();
                               if  (num7!=0){
                               try{
                               double division = num8/num7;
                               
                               c.push(division);}
                               catch(Exception a){}
                               }else{
                                   System.out.println("\nError al dividir por 0");
                                   validar=validar + 1;
                                   i=linea.length();
                               }
                           }
                       }    
                   }
              }
          }
          catch(Exception e){
              e.printStackTrace();
              
          }finally{ // esto se realiza para terminar bien la ejecucion del archivo
              try{
                  
                  if(null!= fr)
                      fr.close();
              
              }catch(Exception e2){
              
              e2.printStackTrace();
              }
          
          }
          
           double result=c.peek(); // en la variable result se guardara el resultado final de la operacion
           if(validar!=1){ // se verifica que el arhivo este bien
               System.out.println("\nEl resultado final es: "+result); // aqui se imprime para poder observar el resultado
           }
      
          
    }
}
